#include "StdAfx.h"
#include "FMDBDataUnloader.h"


CFMDBDataUnloader::CFMDBDataUnloader(void)
{
}


CFMDBDataUnloader::~CFMDBDataUnloader(void)
{
}

int CFMDBDataUnloader::Unloader( int argc, const char* argv[], const char* envp[] )
{
    DWORD StartTime=GetTickCount();
    printf("program start\n");
    //_tprintf(_T("start time:%d\n"),GetTickCount()-StartTime);

    long RowCount=0;

    //analyze arguments			
    int FileIndex=0;//argument index for output file path and name
    int SQLIndex=0;//argument index for SQL script file path and name 
    int UserIndex=0;//argument index for connection string
    int CacheSize=1000;//default 1000,can get from argument
    for (int i=1;i<argc;i++)
    {
        if(_tcsncmp(argv[i],_T("file="),5)==0)
        {
            FileIndex=i;
            continue;
        }
        if(_tcsncmp(argv[i],_T("sql="),4)==0)
        {
            SQLIndex=i;
            continue;
        }
        if(_tcsncmp(argv[i],_T("user="),5)==0)//format must be: "user/password@host:port/service\0"
        {
            UserIndex=i;
            continue;
        }
        if(_tcsncmp(argv[i],_T("cache="),6)==0)//cache size
        {
            CacheSize=i;
            continue;
        }

    }

    //these three arguments cannot be null
    if (FileIndex==0 || SQLIndex==0 || UserIndex==0)
    {
        _tprintf(_T("arguments file= sql= user= must set\n"));
        return -1;
    }

    //connect to db
    //_tprintf(_T("before connect db time:%d\n"),GetTickCount()-StartTime);

    //get user name
    CString strTmp=argv[UserIndex];
    int iUserName=0;
    iUserName=strTmp.Find(_T("/"),0);
    CString strUserName;
    strUserName=strTmp.Mid(5,iUserName-5);

    //get password
    int iPsw=0;
    iPsw=strTmp.Find(_T("@"),iUserName);
    CString strPsw;
    strPsw=strTmp.Mid(iUserName+1,iPsw-iUserName-1);

    //get connection string
    CString strConString;

    strConString=strTmp.Right(strTmp.GetLength()-iPsw-1);

    FMDBApplication& oraDB = FMDBApplication::GetInstance();
    oraDB.SetConnectionString(strConString.GetBuffer());
    oraDB.SetUserName(strUserName.GetBuffer());
    oraDB.SetPassword(strPsw.GetBuffer());

    //open db
    oraDB.OpenDB ();

    //set SQL script file
    strTmp=argv[SQLIndex];
    CString strSQLFile=strTmp.Right(strTmp.GetLength()-4);

    //get exported file
    strTmp=argv[FileIndex];
    CString strExportFile=strTmp.Right(strTmp.GetLength()-5);

    //get sql script
    CStdioFile SQLFile;
    SQLFile.Open(strSQLFile,CFile::modeRead|CFile::typeText);
    CString strSQLScript;
    SQLFile.ReadString(strSQLScript);
    SQLFile.Close();


    //get data
    FMDBConnection conn(&oraDB);
    conn.Open();

    //_tprintf(_T("after connection opened time:%d\n"),GetTickCount()-StartTime);

    FMDBCommand cmd(&conn);
    FMDBRecordSet rs;
    rs.Auto(true);
    rs.SetCacheSize(CacheSize);
    cmd.ExecuteSQL(&rs,strSQLScript.GetBuffer());

    //_tprintf(_T("after executed SQL script time:%d\n"),GetTickCount()-StartTime);

    if (rs.First()==FMSQL_OK)
    {				
        FILE *pf=nullptr;
        pf=_tfopen(argv[FileIndex]+5,_T("w"));
        if (!pf)
        {
            printf("cannot open exported file: %s \n",argv[FileIndex]+5);
            return -1;
        }

        CString field1;				
        do 
        {
            rs.GetString(1,field1);
            _ftprintf(pf,field1);
            _ftprintf(pf,_T("\n"));
            RowCount++;
        } while (rs.Next()==FMSQL_OK);		
        fflush(pf);
        fclose(pf);
    }
    //_tprintf(_T("completed retrieve data,time:%d\n"),GetTickCount()-StartTime);

    printf("row exported:%d\n",RowCount);
    DWORD EndTime=GetTickCount();
    printf("program end, time cost:%d S\n",(EndTime-StartTime)/1000);	

    return 0;

}
